// loader 像是一个个不同的车间 把我们的模块加工成可以使用的文件 loader只是加载模块的环节工作
// loader 大概可以分为3类
// 1、编译转换类
//    例如：css-loader 把css转换为 bundle.js 中的模块 从而实现以JS形式工作的css模块
// 2、文件操作类型的加载器
//    例如：file-loader 把加载到的资源模块拷贝到输出的目录 同时将这个文件的访问路径向外导出
// 3、代码检查类加载器 为了统一代码风格
//    例如：eslint-loader 

// plugins 解决除了资源加载以外 其他的自动化工作 
// 例如 打包之前清除dist目录 或者 拷贝静态文件至输出目录 或是 压缩输出的代码
// plugin 触及到webpack工作的每一个环节 有点像生命周期函数 或者说 钩子函数
// webpack在执行的每一个环节都设置了一个钩子 plugin就是往这些钩子上去挂载任务

// 手写一个plugin plugin 的格式是一个class类 里面有一个apply方法
// apply方法接收一个参数
class MyPlugin {
  // compiler 就是此次webpack工作中最核心的对象
  // 包含了此次webpack构建任务的所有配置信息
  // 以及所有的钩子
  apply(compiler) {
    // emit 钩子就是在即将往 目标目录输出文件时 的钩子
    // .tap 就是往这个钩子上挂载任务
    compiler.hooks.emit.tap('MyPlugin', compilation => {
      // compilation 可以理解为此次打包过程中的上下文
      // 其中assets里就是所有文件的内容的对象 key是文件名 
      // val中有一个source方法可以拿到文件内容
      for (const name in compilation.assets) {
        if (name.endsWith('.js')) { // 判断文件名是否是js结尾
          // val中有一个source方法可以拿到文件内容
          const contents = compilation.assets[name].source();
          // 将js中以 /***...**/ 开头的注释删掉
          const withoutContents = contents.replace(/\/\*\*+\*\//g, '');
          compilation.assets[name] = {
            source: () => withoutContents,
            // val中还必须包含一个size方法得到文件内容的长度
            size: () => withoutContents.length
          }
        }
      }
    });
  }
}

const { resolve } = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = function (env, argv) {
  return {
    // context设置当前webpack的路径 例如这里写了 ../part2 就是把part2作为这个webpack的根路径
    // 那么要访问index.ejs 就需要相对这个路径去找 也就是 ../index.ejs
    // 如果context不设置 那么就是默认package.json的位置为根路径
    // context: resolve(__dirname, '../part2'),
    mode: 'development',
    devServer: {
      open: true,
      hot: true
    },
    // devServer: {
    //   hot: true,
    //   https: true,
    //   proxy: { // 将本地以/bims开头的接口请求转发到后面那个地址
    //     // https://localhost:8080/bims/rest/xxx.jo => https://jiangyin.bimz.cn:8443/bims/rest/xxx.jo
    //     '/bims': {
    //       target: 'https://jiangyin.bimz.cn:8443',
    //       changeOrigin: true // 记得修改主机名字 否则还是localhost:8080  修改之后就是代理主机的名字了
    //     }
    //   }
    // },
    // eval - 是否使用eval执行模块代码
    // cheap - 是否包含行信息
    // module - 是否能够得到loader处理之前的源代码
    devtool: 'cheap-module-eval-source-map',
    resolve: {
      extensions: ['.ts', '.js'],
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          use: ['babel-loader'],
          exclude: /node_modules/,
        }, {
          test: /\.ts$/,
          use: ['babel-loader', 'awesome-typescript-loader'],
          exclude: /node_modules/,
        }, {
          test: /\.(jpg|png|gif)$/,
          use: {
            // url-loader 会把图片等静态资源变成base64存在js文件中 但是这回造成js文件过大 如果静态资源的文件过大 会导致页面显示特别慢
            // file-loader 则不会
            loader: 'url-loader',
            options: {
              // 原理就是placeholder 占位符
              name: '[name]_[hash].[ext]', // 意思是 图片的名字和后缀都不变
              outputPath: 'images/',
              limit: 2048 // 如果文件大于2048字节 则单独打包成文件 否则为base64
            }
          }
        },
        {
          test: /\.css$/,
          // css-loader 分析css之间的关系 比如@import引入其他css
          // style-loader 把解析完之后的css挂载到head标签里
          use: ['style-loader', 'css-loader', 'postcss-loader']
        },
        {
          test: /\.scss$/,
          // webpack中loader的执行顺序是从下到上 从右到左
          // 所以要打包scss的时候先用 sassloader 翻译成css
          // 再用css-loader编译成一个 再防到head中
          use: [
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                importLoaders: 2, // 意思是通过import引入的样式文件在引入之前也要去使用postcss-loader以及sass-loader
                modules: true, // 使用css模块化打包
              }
            },
            'sass-loader',
            'postcss-loader'
          ]
        },
        {
          test: /\.(html)$/,
          use: {
            loader: 'html-loader',
            options: {
              minimize: true,
              attributes: {
                list: [
                  {
                    tag: 'img',
                    attribute: 'data-src',
                    type: 'src',
                  },
                  {
                    tag: 'a',
                    attribute: 'href',
                    type: 'src',
                  },
                ]
              }
            }
          }
        },
        {
          test: /\.md$/,
          use: ['html-loader', './md-loader.js']
        }
      ]
    },
    entry: './part2/module2/webpack/index',
    plugins: [
      // 用于生产index.html
      new HtmlWebpackPlugin({
        // filename: 'index.html', // 设置文件名 默认index.html
        title: 'plugin的title',
        meta: {},
        template: './index.ejs'
      }),
      new CopyWebpackPlugin({
        patterns: [
          { from: 'part2/module2/webpack/assets', to: 'public' },
        ],
      }),
      new MyPlugin(),
      new webpack.HotModuleReplacementPlugin(),
    ],
    output: {
      filename: 'bundle.js',
      path: resolve(__dirname, 'www'),
      publicPath: '',
    },
    optimization: {
      minimize: false
    }
  }
}